<?php
/**
 * WAVESELF FRAMEWORK
 * 
 * Waveself framework is an open source project released under New BSD license.
 * Waveself Engine Team did this in order to help you as ourselves with different
 * but still easy to use and learn approach. 
 * 
 * Please read license before you do any changes or to say, before using current software
 * read our licence which can be found under waveself framework root folder.
 * 
 * If you did not recieve copy of licence, contact us immediately and we will send you copy.
 * 
 * @category   Waveself
 * @package    System Configuration
 * @author     Nevio Vesic <nevio.vesic@gmail.com>
 * @copyright  Waveself Framework NPO 2009-2010
 * @license    https://code.google.com/p/waveself-framework/source/browse/trunk/LICENSE   New-BSD
 * @version    0.1a
 */

/**
 * ...
 * 
 * @category    Waveself
 * @package     Engine
 * @subpackage  Router
 * @author      Nevio Vesic <nevio.vesic@gmail.com>
 * @copyright   Waveself Framework NPO 2009-2010
 * @version     0.1
 */
class Waveself_Engine_Router extends Waveself_Engine_Abstract
{
	/**
	 * Illegal subdomain elements. Primairly built
	 * for checking whenever www is included.
	 *
	 * @var Array
	 */
	private $_illegalSubdomains  = array( 'www' );
	
	/**
	 * Illegal uri elements after we explode current REQUEST_URI
	 *
	 * @var Array
	 */
	private $_illegalUriElements = array( 
		'', '_', '#', '$', '%', '\\', '+', '*', '"', '\'',
		'<', '>', '(', ')', '{', '}', ',', '@', '~', '^' 
	);
	
	/**
	 * Setup routing data... Simple and clear w/o too much
	 * thinking...
	 */
	function __construct()
	{
		/** If request uri is empty or contains / only... */
		if(empty($_SERVER['REQUEST_URI']) || !isset($_SERVER['REQUEST_URI']) 
		   || $_SERVER['REQUEST_URI'] == '/') { self::$_routerData = NULL; }
		   
		/** Horay We got it... */
		else{ self::$_routerData = $this->_prepareUri(); }
	}
	
	private function _prepareUri()
	{
		$uri     = trim(strip_tags(addslashes($_SERVER['REQUEST_URI'])));
		$return  = null;
		
		/** Let's go attempt to explode current uri... Due to possibility
			of dotted uri we will transform all / uri elements into . */
		$uri     = str_ireplace('/', '.', $uri);
		
		/** Quick cleaning... Stage 1 */
		foreach($this->_illegalUriElements as $illegal ) {
			$uri = str_ireplace($illegal, '', $uri);
		}
		
		$uriElms = explode('.', $uri); $realUri = array();
		
		/** Quick cleaning... Stage 2 */
		foreach($uriElms as $element) {
			if(!in_array($element, $this->_illegalUriElements)) {
				$realUri[] = $element;
			}
		}
		
		/** Okay, let's go prepare our request uri :: Stage 1 */
		switch (count($realUri)) {
			
			/** Error! **/
			case 4: throw new Waveself_Exception('Requested url is not valid!'); break;
			
			/** Possible cases are: project, controller, view, params */
			case 3:
					$return[] = $realUri[0];
					$return[] = $realUri[1];
					$data     = $this->_prepareParams($realUri[2]);
					if(isset($data['resource'])) { $return[] = $data['resource']; }
					if(isset($data['params'])) {$return[] = $data['params']; }
				break;
			/** Possible cases are: project, controller, view, params */
			case 2:
					$return[] = $realUri[0];
					$data     = $this->_prepareParams($realUri[1]);
					if(isset($data['resource'])) { $return[] = $data['resource']; }
					if(isset($data['params'])) {$return[] = $data['params']; }
				break;
			/** Possible cases are: project, controller, params */
			case 1:
					$data     = $this->_prepareParams($realUri[0]);
					if(isset($data['resource'])) { $return[] = $data['resource']; }
					if(isset($data['params'])) {$return[] = $data['params']; }
				break;
		}
		
		
		return $return;
	}
	
	/**
	 * Okay, this method will check if there exist view and params.
	 * Case there are params it will return view + params, otherwize it will
	 * return just view or throw Waveself_Exception in case of illegal count.
	 *
	 * @param    String               $data
	 * @return   Array
	 * @throws   Waveself_Exception   If illegal count or illegal characters found! 
	 */
	private function _prepareParams($data)
	{
		$params = explode('?', $data);
		
		if (count($params) == 1) {
			$return['resource'] = $data;
		}
		else if (count($params) == 2) {
			$return['resource'] = $params[0];
			$exploder = explode('&', $params[1]);
			foreach($exploder as $param) {
				$tExplode = explode('=', $param);
				if(!isset($tExplode[1])) throw new Waveself_Exception('Illegal URL!');
				$return['params'][$tExplode[0]] = $tExplode[1]; 
			}
		}
		else if(count($params) > 2) throw new Waveself_Exception('Illegal URL!');
		
		return $return;
	}
	
	/**
	 * Get Router data. Used by Project Engine component
	 *
	 * @return NULL|Array
	 */
	public function getRouterData()
	{
		return self::$_routerData;
	}
	
	/**
	 * Check whenever current HTTP_HOST contain subdomain
	 * different than www
	 *
	 * @return   Boolean
	 */
	public function isSubdomain()
	{
		$match = preg_replace("/^(.*\.)?([^.]*\..*)$/", "$1", $_SERVER['HTTP_HOST']);
		if(in_array($match, $this->_illegalSubdomains)) $match = false;
		return empty($match) ? false : true;
	}
	
	/**
	 * Enter description here...
	 *
	 * @return unknown
	 */
	public function getSubdomain()
	{
		$match = preg_replace("/^(.*\.)?([^.]*\..*)$/", "$1", $_SERVER['HTTP_HOST']);
		if(in_array($match, $this->_illegalSubdomains)) $match = false;
		$match = str_ireplace('.', '', $match);
		return $match ? $match : null;	
	}
	
}